<script lang="ts" setup>
import {
  getRoleList,
  create,
  update,
  del,
  roleForMenu,
  roleForUser,
  cancelRoleForUser,
  saveApi
} from "@/api/system-api/role"
import { getMenuTree, getMenuByRoleId } from "@/api/system-api/menu"
import { Menu as menu } from "@/api/system-api/menu/types/menu"
import { RoleInfo } from "@/api/system-api/role/types/roleinfo"
import { useTableDataMember, useDataDialogMember, useTreeMember } from "@/hooks/commonData/useCommonData"
import { PageQuery } from "./types/pageQuery"
import { nextTick, onMounted, ref } from "vue"
import { Search, Plus, Delete, Edit, Pointer, Refresh, UserFilled, Menu, InfoFilled } from "@element-plus/icons-vue"
import { ElNotification } from "element-plus"
import { ApiRole, NumberBothBind } from "./types/common-bind"
import Node from "element-plus/es/components/tree/src/model/node.mjs"
import RoleUserTable from "./components/roleUserTable.vue"
import { getApiList, getRoleApi } from "@/api/system-api/role"
import { ApiDescription } from "@/api/system-api/role/types/apiRole"
import DictionaryTag from "@/components/DictionaryDisplay/dictionaryTag.vue"
const listQuery: PageQuery = { page: 1, limit: 10 }
const role: RoleInfo = {}
const {
  queryRef,
  resetQuery,
  totalRef,
  tableDataRef,
  tableRef,
  tableLoadingRef,
  getList,
  handleCurrentChange,
  handleSizeChange
} = useTableDataMember(listQuery, getRoleList)
const {
  formRef,
  entityRef,
  dialogStatus,
  currentRef,
  submit,
  getCurrent,
  handleCreate,
  handleUpdate,
  handleDetail,
  handleDelete
} = useDataDialogMember(role, create, update, del, [["id", "roleId"]], getList)
const rules = {
  roleName: [
    {
      required: true,
      message: "请输入用户姓名",
      trigger: "blur"
    }
  ]
}
//#region 这部分是授权菜单代码
const menuForm = ref<NumberBothBind>()
const menuDialog = ref(false)
const { optionsRef, treeRef, getTree } = useTreeMember(getMenuTree)
const handleMenu = async (row: RoleInfo): Promise<void> => {
  menuDialog.value = true
  await roleMenu(row)
}
const optionProp = {
  value: "id",
  label: "menuName",
  children: "children"
}
const roleMenu = async (row: RoleInfo): Promise<void> => {
  menuForm.value = { mainId: undefined, subIds: undefined }
  const query = {} as any
  query.roleId = row.id
  menuForm.value.mainId = row.id
  await getTree()
  nextTick(async () => {
    treeRef.value?.setCheckedKeys([])
    await getMenuByRoleId(query).then((res) => {
      if (res.code === 2000) {
        res.items.forEach((t) => {
          const node = treeRef.value?.getNode(t)
          if (node?.isLeaf) {
            treeRef.value?.setChecked(node, true, true)
          }
        })
      }
    })
  })
}
const submitRoles = async (): Promise<void> => {
  if (menuForm.value?.mainId) {
    menuForm.value.subIds = (treeRef.value!.getCheckedKeys() as number[]).concat(
      treeRef.value!.getHalfCheckedKeys() as number[]
    )
    await roleForMenu(menuForm.value)
      .then((res) => {
        if (res.code === 2001) {
          ElNotification({
            title: "成功!",
            message: "操作成功！",
            type: "success",
            position: "bottom-right"
          })
        }
        menuDialog.value = false
      })
      .then(async () => {
        const temp = { id: menuForm.value?.mainId } as RoleInfo
        await roleMenu(temp)
      })
  }
}
//#endregion
//#region 用户授权
const authDialogStatus = ref(false)
const roleId = ref<number>()
const authTable = ref()
const unAuthTable = ref()
const handleAuth = (row: RoleInfo): void => {
  authDialogStatus.value = true
  roleId.value = row.id
  nextTick(async () => {
    await authTable.value.getList()
    await unAuthTable.value.getList()
  })
}
const commonRole = async (subIds: number[], authApi: (data: NumberBothBind) => Promise<ApiResponseData<boolean>>) => {
  const temp = {} as NumberBothBind
  temp.mainId = roleId.value
  temp.subIds = subIds
  await authApi(temp)
    .then((res) => {
      if (res.code === 2001) {
        ElNotification({
          title: "成功!",
          message: "操作成功！",
          type: "success",
          position: "bottom-right"
        })
      }
    })
    .then(async () => {
      await authTable.value.getList()
      await unAuthTable.value.getList()
    })
}
//#endregion
//#region api授权
const { optionsRef: treeOptionsRef, treeRef: apiTreeRef, getTree: getApiTree } = useTreeMember(getApiList)
const prop = {
  label: "name",
  children: "apiDescriptionList"
}
const apiDialogStatus = ref(false)
const handleApi = async (row: RoleInfo) => {
  roleId.value = row.id
  apiDialogStatus.value = true
  await getApiTree()
  nextTick(async () => {
    const temp = {
      roleId: row.id
    }
    await getRoleApi(temp).then((res) => {
      if (res.code === 2000) {
        const data = res.items
        nextTick(() => {
          data.forEach((t) => {
            //const node=treeRef.value.getNode(t)
            apiTreeRef.value.setChecked(t, true, true)
          })
        })
      }
    })
  })
}
const submitApis = async () => {
  const temp: ApiRole = { mainId: roleId.value }
  temp.subIds = apiTreeRef.value.getCheckedKeys() as string[]
  await saveApi(temp).then((res) => {
    if (res.code === 2001) {
      ElNotification({
        title: "成功!",
        message: "操作成功！",
        type: "success",
        position: "bottom-right"
      })
    }
  })
  console.log(temp)
}
const getTagClass = (method: string): "success" | "warning" | "info" | "primary" | "danger" => {
  switch (method.toUpperCase()) {
    case "GET":
      return "primary"
    case "POST":
      return "success"
    case "PUT":
      return "warning"
    case "DELETE":
      return "danger"
    default:
      return "primary"
  }
}
//#endregion
onMounted(async () => {
  await getList()
})
</script>
<template>
  <div class="app-container">
    <el-row :gutter="0">
      <el-button type="primary" :icon="Search" @click="getList">搜索</el-button>
      <el-button type="primary" :icon="Plus" @click="handleCreate">新增</el-button>
      <el-button :icon="Refresh" @click="resetQuery">重置</el-button>
    </el-row>
    <el-card class="box-card" header="角色管理" style="margin-top: 20px">
      <el-table
        ref="tableRef"
        v-loading="tableLoadingRef"
        :data="tableDataRef"
        :border="true"
        fit
        highlight-current-row
        stripe
        style="width: 100%"
        element-loading-text="给我一点时间"
      >
        <el-table-column label="角色id" prop="id" width="150" />
        <el-table-column label="角色名称" prop="roleName" show-overflow-tooltip />
        <el-table-column label="操作">
          <template #default="scope">
            <el-button-group>
              <el-button type="primary" :icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
              <el-button type="info" :icon="Pointer" @click="handleDetail(scope.row)">详情</el-button>
              <el-button type="success" :icon="Menu" @click="handleMenu(scope.row)">菜单授权</el-button>
              <el-button type="success" :icon="UserFilled" @click="handleAuth(scope.row)">用户授权</el-button>
              <el-button type="success" :icon="InfoFilled" @click="handleApi(scope.row)">接口授权</el-button>
              <el-button type="danger" :icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
            </el-button-group>
          </template>
        </el-table-column>
      </el-table>
      <div style="text-align: center; margin-top: 15px">
        <el-pagination
          :current-page="queryRef.page"
          :page-sizes="[10, 20, 30, 50]"
          :page-size="queryRef.limit"
          layout="total, sizes, prev, pager, next, jumper"
          :total="totalRef"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          style="justify-content: center"
        />
      </div>
    </el-card>
    <el-dialog v-model="dialogStatus" :title="getCurrent()">
      <el-form ref="formRef" :model="entityRef" :rules="rules" label-width="110px">
        <el-row>
          <el-col :span="12">
            <el-form-item label="用户姓名" prop="roleName">
              <el-input v-model="entityRef.roleName" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row style="text-align: center; display: flex; justify-content: center">
          <el-button v-if="currentRef != 3" type="primary" @click="submit">提交</el-button>
          <el-button type="danger" @click="dialogStatus = false">取消</el-button>
        </el-row>
      </el-form>
    </el-dialog>
    <el-dialog v-model="menuDialog" title="菜单授权">
      <el-card :body-style="{ 'min-height': '200px', 'text-align': 'center' }">
        <el-tree ref="treeRef" :data="optionsRef" :props="optionProp" show-checkbox node-key="id" default-expand-all>
          <template #default="{ node, data }: { node: Node; data: menu }">
            <div class="custom-tree-node">
              <DictionaryTag :parent-id="9" :current-value="data.menuType" />
              <span class="pl-1">{{ node.label }}</span>
            </div>
          </template>
        </el-tree>
        <div style="text-align: center">
          <el-button type="primary" @click="submitRoles">授权</el-button>
        </div>
      </el-card>
    </el-dialog>
    <el-dialog v-model="authDialogStatus" title="菜单授权" width="70%">
      <el-row :gutter="20">
        <el-col :span="12">
          <el-card header="已授权用户">
            <RoleUserTable ref="authTable" :is-auth="false" :role-id="roleId" :page="1" :limit="10" />
            <div style="text-align: center; margin-top: 15px">
              <el-button type="primary" @click="commonRole(authTable.getSelection(), roleForUser)">授权</el-button>
            </div>
          </el-card>
        </el-col>
        <el-col :span="12">
          <el-card header="未授权用户">
            <RoleUserTable ref="unAuthTable" :is-auth="true" :role-id="roleId" :page="1" :limit="10" />
            <div style="text-align: center; margin-top: 15px">
              <el-button type="danger" @click="commonRole(unAuthTable.getSelection(), cancelRoleForUser)"
                >取消授权</el-button
              >
            </div>
          </el-card>
        </el-col>
      </el-row>
    </el-dialog>
    <el-dialog v-model="apiDialogStatus" title="接口授权">
      <el-card>
        <el-tree ref="apiTreeRef" :data="treeOptionsRef" :props="prop" node-key="id" show-checkbox>
          <template #default="{ data }: { node: Node; data: ApiDescription }">
            <el-tag size="default" type="info" v-if="data.apiDescriptionList" round>controller</el-tag>
            <el-tag size="default" type="success" v-else round>action</el-tag>
            <div v-if="data.method">
              <el-tag size="small" :type="getTagClass(data.method)">{{ data.method }}</el-tag>
            </div>
            <el-popover placement="top-start" title="描述" :width="200" trigger="hover" :content="data.description">
              <template #reference>
                {{ data.name }}
              </template>
            </el-popover>
          </template>
        </el-tree>
        <div style="text-align: center">
          <el-button type="primary" @click="submitApis">授权</el-button>
        </div>
      </el-card>
    </el-dialog>
  </div>
</template>

<style scoped></style>
